package com.tan.kotlintest.net

import com.tan.kotlintest.util.LogUtil
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.concurrent.*


/*
 * Copyright (C) 2018 重庆一聊高科技有限公司
 * 版权所有
 *
 * 功能描述:  网络管理工具类
 * 作者：txj
 * 创建时间：2018/9/18
 *
 * 修改人：
 * 修改描述：
 * 修改日期
 */
class NetTaskManager private constructor() {

    //线程池
    private var mThreadPoolExecutor: ThreadPoolExecutor? = null

    //初始化
    init {
        //线程池
        mThreadPoolExecutor = ThreadPoolExecutor(3, 15,
                15, TimeUnit.SECONDS, object : ArrayBlockingQueue<Runnable>(4),
                RejectedExecutionHandler {
            override fun rejectedExecution(r: Runnable?, executor: ThreadPoolExecutor?) {
            }
        })
        //开始核心线程
        val loopThread = LoopThread()
        mThreadPoolExecutor?.execute(loopThread)
    }

    //任务队列
    private val mLinkedBlockingQueue: LinkedBlockingQueue<TaskThread>? = LinkedBlockingQueue()

    /**
     * 添加任务到队列
     *
     * 添加之后 取任务线程会自动取出来,然后执行
     */
    public fun executeTask(netTask: NetTask) {
        val taskThread = TaskThread(netTask)
        mLinkedBlockingQueue?.add(taskThread)
    }

    /**
     * 核心线程 取任务的线程
     * 使用while死循环 无限取
     */
    private inner class LoopThread : Runnable {

        override fun run() {
            while (true) {
                val taskThread = mLinkedBlockingQueue?.take() as TaskThread
                mThreadPoolExecutor?.execute(taskThread)
            }
        }

    }


    /**
     * 工作线程
     *
     * 传入任务的参数: url  方法
     */
    private inner class TaskThread(netTask: NetTask) : Runnable {

        private var mNetTask: NetTask = netTask

        override fun run() {
            var httpURLConnection: HttpURLConnection? = null
            try {
                val url = URL(mNetTask.url)
                LogUtil.i("开始请求:${mNetTask.url}  +  请求方法: ${mNetTask.method}")
                httpURLConnection = url.openConnection() as HttpURLConnection
                httpURLConnection.requestMethod = "GET"//请求方式
                httpURLConnection.readTimeout = 8000//读取超时
                httpURLConnection.connectTimeout = 8000//写超时
                // 配置请求Content-Type
                httpURLConnection.setRequestProperty("Content-Type", "application/json")
                // 开始连接
                httpURLConnection.connect()
                if (httpURLConnection.responseCode == 200) {//请求成功
                    //获取数据
                    val inputStream = httpURLConnection.inputStream
                    val response = streamToStr(inputStream, "utf-8")
                    LogUtil.i("请求返回: $response")
                } else {
                    LogUtil.i("请求失败: ${httpURLConnection.responseCode}")
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                //关闭连接
                httpURLConnection?.disconnect()
            }
        }

    }

    //单例
    companion object {
        var instance: NetTaskManager = NetTaskManager()
    }

    /**
     * 将输入流转换成字符串
     *
     * @param inputStream 从网络获取的输入流
     * @return
     */
    fun streamToStr(inputStream: InputStream, chartSet: String): String {
        val builder = StringBuilder()
        try {
            val br = BufferedReader(InputStreamReader(inputStream, chartSet))
            //Kotlin中读取流的写法
            var con: String?
            while (br.readLine().also { con = it } != null) {
                builder.append(con)
            }
            br.close()
            return builder.toString()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return ""
    }

}